package com.zerone.aidlstudy;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

public class MyService extends Service {
    private final String TAG = "MyService";
    private NotificationManager notificationMgr;
    private AtomicBoolean canRun = new AtomicBoolean(true);
    public static final int NOTIFICATION_COMMON_ID = 1;

    private final List<Employee> employees = new ArrayList<>();
    private RemoteCallbackList<IOnSalaryPaidListener> listenerList = new RemoteCallbackList<>();

    //实现IMyService aidl文件中的抽象方法
    private final IMyService.Stub mBinder = new IMyService.Stub() {

        @Override
        public List<Employee> getEmployee() throws RemoteException {
            synchronized (employees) {
                return employees;
            }
        }

        @Override
        public void addEmployee(Employee employee) throws RemoteException {
            synchronized (employees) {
                if (!employees.contains(employee)) {
                    employees.add(employee);
                }
            }
        }

        @Override
        public void registerListener(IOnSalaryPaidListener listener) throws RemoteException {
            listenerList.register(listener);
            int N = listenerList.beginBroadcast();
            listenerList.finishBroadcast();
            Log.d(TAG, "registerListener, current size: " + N);
        }

        @Override
        public void unregisterListener(IOnSalaryPaidListener listener) throws RemoteException {
            boolean success = listenerList.unregister(listener);
            if (!success) {
                Log.d(TAG, "unregister fail...");
            } else {
                Log.d(TAG, "unregister success!!");
            }
            int N = listenerList.beginBroadcast();
            listenerList.finishBroadcast();
            Log.d(TAG, "unregisterListener, current size: " + N);
        }

        //可以在这里做权限认证，return false意味着客户端的调用会失败，
        @Override
        public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            boolean result = super.onTransact(code, data, reply, flags);
            int check = checkCallingOrSelfPermission("com.zerone.aidlstudy.permission.ACCESS_BOOK_SERVICE");
            Log.d(TAG, "check=" + check);
            if (check == PackageManager.PERMISSION_DENIED) {
                return false;
            }
            String pkgName = null;
            String[] packages = MyService.this.getPackageManager().getPackagesForUid(getCallingUid());
            if (packages != null && packages.length > 0) {
                pkgName = packages[0];
            }
            Log.d(TAG, "packageName=" + pkgName);
            return !(pkgName == null || !pkgName.startsWith("com.zerone")) && result;
        }
    };

    @Override
    public void onCreate() {
        Thread thread = new Thread(null, new ServiceWorker(), "BackgroundService");
        thread.start();

        synchronized (employees) {
            Random random = new Random();
            for (int i = 0; i < 10; i++) {
                Employee employee = new Employee();
                employee.sno = i + 1;
                employee.name = "Employee#" + i;
                employee.age = 21 + random.nextInt(6);
                if (random.nextInt(2) == 1) {
                    employee.gender = Employee.SEX_MALE;
                } else {
                    employee.gender = Employee.SEX_FEMALE;
                }
                employee.salary = 8000;
                employees.add(employee);
            }
        }
        notificationMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        super.onCreate();
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind, intent=" + intent.toString());
        displayNotificationMessage("服务已启动");
        return mBinder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand, intent=" + intent.toString());
        displayNotificationMessage("服务已启动", true);
        return super.onStartCommand(intent, flags, startId);
    }

    private void displayNotificationMessage(String msg, boolean isForeground) {
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, MainActivity.class), 0);
        Notification notification = new Notification.Builder(this)
                .setAutoCancel(true)
                .setContentTitle("MyService")
                .setContentText(msg)
                .setContentIntent(contentIntent)
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setWhen(System.currentTimeMillis())
                .build();
        if (isForeground) {
            startForeground(NOTIFICATION_COMMON_ID, notification);
        } else {
            notificationMgr.notify(NOTIFICATION_COMMON_ID, notification);
        }
    }

    private void displayNotificationMessage(String msg) {
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, MainActivity.class), 0);
        Notification notification = new Notification.Builder(this)
                .setAutoCancel(true)
                .setContentTitle("我的通知")
                .setContentText(msg)
                .setContentIntent(contentIntent)
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setWhen(System.currentTimeMillis())
                .build();
        notificationMgr.notify(NOTIFICATION_COMMON_ID + 1, notification);
    }

    @Override
    public void onDestroy() {
        stopForeground(true);
        canRun.set(false);
        super.onDestroy();
    }

    /**
     * service自身的线程，用于做自己的事情，
     */
    private class ServiceWorker implements Runnable {
        int count = 0;

        @Override
        public void run() {
            while (canRun.get()) {
                Log.d(TAG, "ServiceWorker count=" + count);
                count++;

                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                payEmployeeSalary();
            }
        }
    }

    private void payEmployeeSalary() {
        final int N = listenerList.beginBroadcast();
        for (int i = 0; i < N; i++) {
            IOnSalaryPaidListener listener = listenerList.getBroadcastItem(i);
            if (listener != null) {
                try {
                    listener.onSalaryPaid();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
        listenerList.finishBroadcast();
    }

}
